home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / spots.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.6 KB  |  438 lines

  1. /*
  2.  * Copyright 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include <GL/gl.h>
  22. #include <GL/glx.h>
  23. #include <X11/Xlib.h>
  24. #include <X11/keysym.h>
  25.  
  26. #define TWO_PI    (2*M_PI)
  27.  
  28. typedef struct lightRec {
  29.     float amb[4];
  30.     float diff[4];
  31.     float spec[4];
  32.     float pos[4];
  33.     float spotDir[3];
  34.     float spotExp;
  35.     float spotCutoff;
  36.     float atten[3];
  37.  
  38.     float trans[3];
  39.     float rot[3];
  40.     float swing[3];
  41.     float arc[3];
  42.     float arcIncr[3];
  43. } Light;
  44.  
  45. static int useSAME_AMB_SPEC = 1;
  46.  
  47. static float modelAmb[4] = { 0.2, 0.2, 0.2, 1.0 };
  48.  
  49. static float matAmb[4] = { 0.2, 0.2, 0.2, 1.0 };
  50. static float matDiff[4] = { 0.8, 0.8, 0.8, 1.0 };
  51. static float matSpec[4] = { 0.4, 0.4, 0.4, 1.0 };
  52. static float matEmission[4] = { 0.0, 0.0, 0.0, 1.0 };
  53.  
  54. static char *geometry = NULL;
  55.  
  56. #define NUM_LIGHTS 3
  57. static Light spots[] = {
  58.     {
  59.     { 0.2, 0.0, 0.0, 1.0 },            /* ambient */
  60.     { 0.8, 0.0, 0.0, 1.0 },            /* diffuse */
  61.     { 0.4, 0.0, 0.0, 1.0 },            /* specular */
  62.     { 0.0, 0.0, 0.0, 1.0 },            /* position */
  63.     { 0.0, -1.0, 0.0 },            /* direction */
  64.     { 20.0 }, { 60.0 },            /* exponent, cutoff */
  65.     { 1.0, 0.0, 0.0 },            /* attenuation */
  66.     { 0.0, 1.25, 0.0 },            /* translation */
  67.     { 0.0, 0.0, 0.0 },            /* rotation */
  68.     { 20.0, 0.0, 40.0 },            /* swing */
  69.     { 0.0, 0.0, 0.0 },            /* arc */
  70.     { TWO_PI/70.0, 0.0, TWO_PI/140.0 }    /* arc increment */
  71.     },
  72.     {
  73.     { 0.0, 0.2, 0.0, 1.0 },            /* ambient */
  74.     { 0.0, 0.8, 0.0, 1.0 },            /* diffuse */
  75.     { 0.0, 0.4, 0.0, 1.0 },            /* specular */
  76.     { 0.0, 0.0, 0.0, 1.0 },            /* position */
  77.     { 0.0, -1.0, 0.0 },            /* direction */
  78.     { 20.0 }, { 60.0 },            /* exponent, cutoff */
  79.     { 1.0, 0.0, 0.0 },            /* attenuation */
  80.     { 0.0, 1.25, 0.0 },            /* translation */
  81.     { 0.0, 0.0, 0.0 },            /* rotation */
  82.     { 20.0, 0.0, 40.0 },            /* swing */
  83.     { 0.0, 0.0, 0.0 },            /* arc */
  84.     { TWO_PI/120.0, 0.0, TWO_PI/60.0 }    /* arc increment */
  85.     },
  86.     {
  87.     { 0.0, 0.0, 0.2, 1.0 },            /* ambient */
  88.     { 0.0, 0.0, 0.8, 1.0 },            /* diffuse */
  89.     { 0.0, 0.0, 0.4, 1.0 },            /* specular */
  90.     { 0.0, 0.0, 0.0, 1.0 },            /* position */
  91.     { 0.0, -1.0, 0.0 },            /* direction */
  92.     { 20.0 }, { 60.0 },            /* exponent, cutoff */
  93.     { 1.0, 0.0, 0.0 },            /* attenuation */
  94.     { 0.0, 1.25, 0.0 },            /* translation */
  95.     { 0.0, 0.0, 0.0 },            /* rotation */
  96.     { 20.0, 0.0, 40.0 },            /* swing */
  97.     { 0.0, 0.0, 0.0 },            /* arc */
  98.     { TWO_PI/50.0, 0.0, TWO_PI/100.0 }    /* arc increment */
  99.     }
  100. };
  101.  
  102. static void
  103. usage(int argc, char **argv)
  104. {
  105.     printf("\n");
  106.     printf("usage: %s [options]\n", argv[0]);
  107.     printf("\n");
  108.     printf("  Options:\n");
  109.     printf("    -geometry Specify size and position WxH+X+Y\n");
  110.     printf("    -lm       Toggle lighting(SPECULAR and AMBIENT are/not same\n");
  111.     printf("\n");
  112.     exit(EXIT_FAILURE);
  113. }
  114.  
  115. static void
  116. initLights(void)
  117. {
  118.     int k;
  119.  
  120.     for (k=0; k<NUM_LIGHTS; ++k) {
  121.     int lt = GL_LIGHT0+k;
  122.     Light *light = &spots[k];
  123.  
  124.     glEnable(lt);
  125.     glLightfv(lt, GL_AMBIENT, light->amb);
  126.     glLightfv(lt, GL_DIFFUSE, light->diff);
  127.  
  128.     if (useSAME_AMB_SPEC)
  129.         glLightfv(lt, GL_SPECULAR, light->amb);
  130.         else
  131.         glLightfv(lt, GL_SPECULAR, light->spec);
  132.  
  133.     glLightf(lt, GL_SPOT_EXPONENT, light->spotExp);
  134.     glLightf(lt, GL_SPOT_CUTOFF, light->spotCutoff);
  135.     glLightf(lt, GL_CONSTANT_ATTENUATION, light->atten[0]);
  136.     glLightf(lt, GL_LINEAR_ATTENUATION, light->atten[1]);
  137.     glLightf(lt, GL_QUADRATIC_ATTENUATION, light->atten[2]);
  138.     }
  139. }
  140.  
  141. static void
  142. aimLights(void)
  143. {
  144.     int k;
  145.  
  146.     for (k=0; k<NUM_LIGHTS; ++k) {
  147.     Light *light = &spots[k];
  148.  
  149.     light->rot[0] = light->swing[0] * sin(light->arc[0]);
  150.     light->arc[0] += light->arcIncr[0];
  151.     if (light->arc[0] > TWO_PI) light->arc[0] -= TWO_PI;
  152.  
  153.     light->rot[1] = light->swing[1] * sin(light->arc[1]);
  154.     light->arc[1] += light->arcIncr[1];
  155.     if (light->arc[1] > TWO_PI) light->arc[1] -= TWO_PI;
  156.  
  157.     light->rot[2] = light->swing[2] * sin(light->arc[2]);
  158.     light->arc[2] += light->arcIncr[2];
  159.     if (light->arc[2] > TWO_PI) light->arc[2] -= TWO_PI;
  160.     }
  161. }
  162.  
  163. static void
  164. setLights(void)
  165. {
  166.     int k;
  167.  
  168.     for (k=0; k<NUM_LIGHTS; ++k) {
  169.     int lt = GL_LIGHT0+k;
  170.     Light *light = &spots[k];
  171.  
  172.     glPushMatrix();
  173.     glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
  174.     glRotatef(light->rot[0], 1, 0, 0);
  175.     glRotatef(light->rot[1], 0, 1, 0);
  176.     glRotatef(light->rot[2], 0, 0, 1);
  177.     glLightfv(lt, GL_POSITION, light->pos);
  178.     glLightfv(lt, GL_SPOT_DIRECTION, light->spotDir);
  179.     glPopMatrix();
  180.     }
  181. }
  182.  
  183. static void
  184. drawLights(void)
  185. {
  186.     int k;
  187.  
  188.     glDisable(GL_LIGHTING);
  189.     for (k=0; k<NUM_LIGHTS; ++k) {
  190.     Light *light = &spots[k];
  191.  
  192.     glColor4fv(light->diff);
  193.  
  194.     glPushMatrix();
  195.     glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
  196.     glRotatef(light->rot[0], 1, 0, 0);
  197.     glRotatef(light->rot[1], 0, 1, 0);
  198.     glRotatef(light->rot[2], 0, 0, 1);
  199.     glBegin(GL_LINES);
  200.     glVertex3f(light->pos[0], light->pos[1], light->pos[2]);
  201.     glVertex3f(light->spotDir[0], light->spotDir[1], light->spotDir[2]);
  202.     glEnd();
  203.     glPopMatrix();
  204.     }
  205.     glEnable(GL_LIGHTING);
  206. }
  207.  
  208. static void
  209. drawPlane(int w, int h)
  210. {
  211.     int i, j;
  212.     float dw = 1.0/w;
  213.     float dh = 1.0/h;
  214.  
  215.     glNormal3f(0.0, 0.0, 1.0);
  216.     for (j=0; j<h; ++j) {
  217.     glBegin(GL_TRIANGLE_STRIP);
  218.     for (i=0; i<=w; ++i) {
  219.         glVertex2f(dw * i, dh * (j+1));
  220.         glVertex2f(dw * i, dh * j);
  221.     }
  222.     glEnd();
  223.     }
  224. }
  225.  
  226. static Bool
  227. waitForNotify(Display *dpy, XEvent *event, XPointer arg)
  228. {
  229.     return (event->type == MapNotify && event->xmap.window == (Window) arg);
  230. }
  231.  
  232. static void
  233. windopen(Display **dpy_ret, Window *win_ret, GLXContext *ctx_ret,
  234.       char *name, int w, int h, int argc, char **argv)
  235. {
  236.     static int visAttrs[] = {
  237.     GLX_RGBA,
  238.     GLX_DOUBLEBUFFER,
  239.     GLX_RED_SIZE, 1,
  240.     GLX_GREEN_SIZE, 1,
  241.     GLX_BLUE_SIZE, 1,
  242.     None
  243.     };
  244.     static Display *dpy = NULL;
  245.     int scr;
  246.     Window root;
  247.     XVisualInfo *xvis;
  248.     GLXContext ctx;
  249.     XSetWindowAttributes xswa;
  250.     XSizeHints sizehints;
  251.     Colormap cmap;
  252.     Window win;
  253.     XEvent event;
  254.  
  255.     if (dpy == NULL) {
  256.     if ((dpy = XOpenDisplay(NULL)) == NULL) {
  257.         fprintf(stderr, "can't open display\n");
  258.         exit(EXIT_FAILURE);
  259.     }
  260.     }
  261.     scr = DefaultScreen(dpy);
  262.     root = RootWindow(dpy, scr);
  263.  
  264.     if ((xvis = glXChooseVisual(dpy, scr, visAttrs)) == NULL) {
  265.     fprintf(stderr, "can't find visual\n");
  266.     exit(EXIT_FAILURE);
  267.     }
  268.  
  269.     if ((ctx = glXCreateContext(dpy, xvis, NULL, True)) == None) {
  270.     fprintf(stderr, "can't create context\n");
  271.     exit(EXIT_FAILURE);
  272.     }
  273.  
  274.     if ((cmap = XCreateColormap(dpy, root, xvis->visual, AllocNone)) == None) {
  275.     fprintf(stderr, "can't create colormap\n");
  276.     exit(EXIT_FAILURE);
  277.     }
  278.  
  279.     sizehints.flags = PPosition | PSize;
  280.     sizehints.width = w;
  281.     sizehints.height = h;
  282.     sizehints.x = 0;
  283.     sizehints.y = 0;
  284.     if (geometry) {
  285.     int flags, x, y, width, height;
  286.  
  287.     flags = XParseGeometry(geometry, &x, &y,
  288.                    (unsigned int *)&width,
  289.                    (unsigned int *)&height);
  290.         if(WidthValue & flags) {
  291.         sizehints.flags |= USSize;
  292.         sizehints.width = width;
  293.         w = width;
  294.         }
  295.     if(HeightValue & flags) {
  296.         sizehints.flags |= USSize;
  297.         sizehints.height = height;
  298.         h = height;
  299.     }
  300.     if(XValue & flags) {
  301.         if(XNegative & flags)
  302.         x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
  303.             - sizehints.width;
  304.             sizehints.flags |= USPosition;
  305.         sizehints.x = x;
  306.     }
  307.     if(YValue & flags) {
  308.         if(YNegative & flags)
  309.         y = DisplayHeight(dpy, DefaultScreen(dpy)) + y 
  310.             - sizehints.height;
  311.             sizehints.flags |= USPosition;
  312.         sizehints.y = y;
  313.     }
  314.     }
  315.     xswa.colormap = cmap;
  316.     xswa.background_pixel = 0;
  317.     xswa.border_pixel = 0;
  318.     xswa.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask;
  319.     win = XCreateWindow(dpy, root, sizehints.x, sizehints.y,
  320.             sizehints.width, sizehints.height, 0,
  321.             xvis->depth, InputOutput, xvis->visual,
  322.             CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
  323.             &xswa);
  324.  
  325.     XSetStandardProperties(dpy, win, name, name, None,
  326.                            argv, argc, &sizehints);
  327.  
  328.     XMapWindow(dpy, win);
  329.     XIfEvent(dpy, &event, waitForNotify, (XPointer) win);
  330.  
  331.     glXMakeCurrent(dpy, win, ctx);
  332.  
  333.     *dpy_ret = dpy;
  334.     *win_ret = win;
  335.     *ctx_ret = ctx;
  336. }
  337.  
  338. int
  339. main(int argc, char **argv)
  340. {
  341.     Display *dpy;
  342.     Window win;
  343.     GLXContext ctx;
  344.     int width = 300, height = 300;
  345.     float spin = 0.0;
  346.     int i;
  347.  
  348.     /* process commmand line args */
  349.     for (i = 1; i < argc; ++i)
  350.     {
  351.     if (!strcmp("-geometry", argv[i]))
  352.     {
  353.         i++;
  354.         geometry = argv[i];
  355.         if (geometry == NULL) {
  356.         usage(argc, argv);
  357.         }
  358.     }
  359.         else if (!strcmp("-lm", argv[i]))
  360.         {
  361.             useSAME_AMB_SPEC = !useSAME_AMB_SPEC;
  362.         }
  363.         else
  364.         {
  365.             usage(argc, argv);
  366.         }
  367.     }
  368.  
  369.     windopen(&dpy, &win, &ctx, "spotlight swing", width, height, argc, argv);
  370.  
  371.     glMatrixMode(GL_PROJECTION);
  372.     glFrustum(-1, 1, -1, 1, 2, 6);
  373.  
  374.     glMatrixMode(GL_MODELVIEW);
  375.     glTranslatef(0.0, 0.0, -3.0);
  376.     glRotatef(45.0, 1, 0, 0);
  377.  
  378.     glEnable(GL_LIGHTING);
  379.     glEnable(GL_NORMALIZE);
  380.  
  381.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
  382.     glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
  383.     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  384.  
  385.     glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
  386.     glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
  387.     glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
  388.     glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
  389.     glMaterialf(GL_FRONT, GL_SHININESS, 10.0);
  390.  
  391.     initLights();
  392.  
  393.     while (1) {
  394.     if (XPending(dpy)) {
  395.         XEvent event;
  396.         KeySym ks;
  397.  
  398.         XNextEvent(dpy, &event);
  399.         switch(event.type) {
  400.           case KeyPress:
  401.         XLookupString(&event.xkey, NULL, 0, &ks, NULL);
  402.         if (ks == XK_Escape) {
  403.             exit(EXIT_SUCCESS);
  404.         }
  405.         break;
  406.           case ConfigureNotify:
  407.         width = event.xconfigure.width;
  408.         height = event.xconfigure.height;
  409.         glViewport(0, 0, width, height);
  410.         break;
  411.           default:
  412.         break;
  413.         }
  414.     }
  415.  
  416.     glClear(GL_COLOR_BUFFER_BIT);
  417.  
  418.     glPushMatrix();
  419.     glRotatef(spin += 0.5, 0, 1, 0);
  420.     if (spin > 360.0) spin -= 360.0;
  421.  
  422.     aimLights();
  423.     setLights();
  424.  
  425.     glPushMatrix();
  426.     glRotatef(-90.0, 1, 0, 0);
  427.     glScalef(1.9, 1.9, 1.0);
  428.     glTranslatef(-0.5, -0.5, 0.0);
  429.     drawPlane(16, 16);
  430.     glPopMatrix();
  431.  
  432.     drawLights();
  433.     glPopMatrix();
  434.  
  435.     glXSwapBuffers(dpy, win);
  436.     }
  437. }
  438.